import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.PrintStream;
import java.net.Socket;
import java.security.KeyStore;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLException;
import javax.net.ssl.SSLServerSocket;
import javax.net.ssl.TrustManagerFactory;

public class MutualSSLServer {

	private static final int DEFAULT_PORT = 7777;

	private static final String SERVER_KEY_STORE_PASSWORD = "123456";
	private static final String SERVER_TRUST_KEY_STORE_PASSWORD = "123456";

	private SSLServerSocket serverSocket;

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		MutualSSLServer server = new MutualSSLServer();
		server.init();
		server.start();
	}

	public void init() {
		try {
			SSLContext ctx = SSLContext.getInstance("SSL");

			KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
			TrustManagerFactory tmf = TrustManagerFactory
					.getInstance("SunX509");

			KeyStore ks = KeyStore.getInstance("JKS");
			KeyStore tks = KeyStore.getInstance("JKS");

			ks.load(new FileInputStream("test/node_a_keystore.jks"),
					SERVER_KEY_STORE_PASSWORD.toCharArray());
			tks.load(new FileInputStream("test/ca_keystore.jks"),
					SERVER_TRUST_KEY_STORE_PASSWORD.toCharArray());

			kmf.init(ks, SERVER_KEY_STORE_PASSWORD.toCharArray());
			tmf.init(tks);

			ctx.init(kmf.getKeyManagers(), tmf.getTrustManagers(), null);

			serverSocket = (SSLServerSocket) ctx.getServerSocketFactory()
					.createServerSocket(DEFAULT_PORT);
			serverSocket.setNeedClientAuth(true);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public void start() {
		if (serverSocket == null) {
			System.out.println("ERROR");
			return;
		}
		System.out.println("Server is up and running");
		while (true) {
			try {
				Socket s = serverSocket.accept();
				InputStream is = null;
				is = s.getInputStream();
				ByteArrayOutputStream baos = new ByteArrayOutputStream();
				byte[] aByte = new byte[1];
				int bytesRead;
				if (is != null) {

					FileOutputStream fos = null;
					BufferedOutputStream bos = null;
					try {
						fos = new FileOutputStream("receive");
						bos = new BufferedOutputStream(fos);
						bytesRead = is.read(aByte, 0, aByte.length);

						do {
							baos.write(aByte);
							bytesRead = is.read(aByte);
						} while (bytesRead != -1);

						bos.write(baos.toByteArray());
						System.out.println("received: " + baos.size());
						bos.flush();
						bos.close();
						
					} catch(SSLException sslex){
						System.out.println("SSL required");
						
					}
					catch (IOException ex) {
						System.err.println(ex.toString());
						ex.printStackTrace();
					}
				}

				s.close();
			} catch (Exception e) {
				
				e.printStackTrace();
				
			}
		}
	}

}
